package pe.com.casadesign.dao.impl;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;

import javax.sql.DataSource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
import org.springframework.jdbc.core.simple.SimpleJdbcCall;
import org.springframework.stereotype.Repository;

import pe.com.casadesign.dao.GuiaDAO;
import pe.com.casadesign.domain.Bulto;
import pe.com.casadesign.domain.Guia;
import pe.com.casadesign.domain.Item;
import pe.com.casadesign.domain.ItemComponente;
import pe.com.casadesign.domain.LineaDetalleBulto;
import pe.com.casadesign.domain.LineaGuia;
import pe.com.casadesign.domain.LineaGuiaBulto;
import pe.com.casadesign.domain.LineaGuiaItem;
import pe.com.casadesign.domain.LineaSolicitudBulto;
import pe.com.casadesign.domain.ListaItem;
import pe.com.casadesign.domain.ListaGuia;
import pe.com.casadesign.domain.ListaItemComponente;
import pe.com.casadesign.domain.ListaLineaGuia;
import pe.com.casadesign.domain.ListaLineaGuiaBulto;
import pe.com.casadesign.domain.ListaLineaGuiaItem;
import pe.com.casadesign.domain.ListaLineaSolicitudBulto;
import pe.com.casadesign.domain.ListaOrdenCompra;
import pe.com.casadesign.domain.LineaOrdenCompra;
import pe.com.casadesign.domain.NivelColor;
import pe.com.casadesign.domain.NivelMaterial;
import pe.com.casadesign.domain.NivelProducto;
import pe.com.casadesign.domain.NivelTipo;
import pe.com.casadesign.domain.OrdenCompra;
import pe.com.casadesign.domain.Moneda;
import pe.com.casadesign.domain.Mantenimiento;
import pe.com.casadesign.domain.Venta;
import pe.com.casadesign.domain.Solicitud;
import pe.com.casadesign.domain.Prestamo;
import pe.com.casadesign.domain.Transporte;
import pe.com.casadesign.domain.TipoGuia;
import pe.com.casadesign.domain.Producto;
import pe.com.casadesign.domain.Tienda;
import pe.com.casadesign.domain.Cliente;
import pe.com.casadesign.domain.Diseniador;
import pe.com.casadesign.domain.Usuario;

/**
 * Implementacion de GuiaDAO.
 * 
 * @author Pedro Vera
 * 
 */
@Repository
public class GuiaDAOImpl implements GuiaDAO {
	private static final Logger logger = LoggerFactory.getLogger(GuiaDAOImpl.class);
	
	// Nombre Procedimientos Almacenados
	private static String SP_REGISTRAR_GUIA = "SP_REGISTRAR_GUIA";
	private static String SP_REGISTRAR_GUIA_ORDENCOMPRA = "SP_REGISTRAR_GUIA_ORDENCOMPRA";
	private static String SP_REGISTRAR_DET_GUIA = "SP_REGISTRAR_DET_GUIA";
	private static String SP_REGISTRAR_DET_GUIA_ITEM = "SP_REGISTRAR_DET_GUIA_ITEM";
	private static String SP_OBTENER_GUIA = "SP_OBTENER_GUIA";
	private static String SP_OBTENER_GUIA_CODGUIA = "SP_OBTENER_GUIA_CODGUIA";
	private static String SP_MODIFICAR_GUIA = "SP_MODIFICAR_GUIA";
	private static String SP_OBTENER_GUIA_ORDENCOMPRA = "SP_OBTENER_GUIA_ORDENCOMPRA";
	private static String SP_VALIDAR_GUIA = "SP_VALIDAR_GUIA";
	private static String SP_LIMPIAR_GUIA_ORDENCOMPRA = "SP_LIMPIAR_GUIA_ORDENCOMPRA";
	private static String SP_LIMPIAR_GUIA_DETALLE = "SP_LIMPIAR_GUIA_DETALLE";
	private static String SP_LISTAR_PRESTAMO_GUIA = "SP_LISTAR_PRESTAMO_GUIA";
	
	private static String SP_REGISTRAR_ITEM = "SP_REGISTRAR_ITEM";
	private static String SP_ACTUALIZAR_ESTADO_ITEM = "SP_ACTUALIZAR_ESTADO_ITEM";
	private static String SP_REGISTRAR_ITEM_COMPONENTE = "SP_REGISTRAR_ITEM_COMPONENTE";
	private static String SP_ACTUALIZAR_ESTADO_ORDENCOMPRA = "SP_ACTUALIZAR_ESTADO_ORDENCOMPRA";
	private static String SP_MODIFICAR_DET_ORDENCOMPRA = "SP_MODIFICAR_DET_ORDENCOMPRA";
	
	private static String SP_REGISTRAR_BULTO = "SP_REGISTRAR_BULTO";
	private static String SP_REGISTRAR_DET_BULTO = "SP_REGISTRAR_DET_BULTO";
	private static String SP_REGISTRAR_GUIA_BULTO = "SP_REGISTRAR_GUIA_BULTO";
	private static String SP_OBTENER_GUIA_BULTO  = "SP_OBTENER_GUIA_BULTO";
	private static String SP_ACTUALIZAR_ESTADO_GUIA = "SP_ACTUALIZAR_ESTADO_GUIA";
	
	
	// Parametros de Entrada
	private static String PARAM_CODGUIA = "p_codguia";
	private static String PARAM_CODTIENDADESTINO = "p_codtiendadestino";
	private static String PARAM_CODTIENDAORIGEN = "p_codtiendaorigen";
	private static String PARAM_CODTIPOGUIA = "p_codtipoguia";
	private static String PARAM_NUMERO = "p_numero";
	private static String PARAM_SERIE = "p_serie";
	private static String PARAM_CODTRANSPORTE = "p_codtransporte"; 
	private static String PARAM_CODVENTA = "p_codventa"; 
	private static String PARAM_CODSOLICITUD =	"p_codsolicitud";
	private static String PARAM_CODPRESTAMO = "p_codprestamo";
	private static String PARAM_CODMANTENIMIENTO = "p_codmantenimiento";
	private static String PARAM_FECHAEMISION = "p_fechaemision";
	private static String PARAM_ESTADO = "p_estado"; 
	private static String PARAM_FECHARECEPCION = "p_fecharecepcion";
	
	private static String PARAM_GUIAOC_CODOC = "p_codoc";
	private static String PARAM_GUIAOC_ESTADO = "p_estado";
	
	private static String PARAM_DET_NROLINEA = "p_nrolinea";
	private static String PARAM_DET_NROLINEA_REG = "p_nrolinea_reg";
	private static String PARAM_DET_CODPRODUCTO = "p_codproducto";
	
	private static String PARAM_DET_CANTIDAD = "p_cantidad";
	private static String PARAM_DET_CANTIDADRECIBIDA = "p_cantidadrecibida";
	private static String PARAM_DET_ESTADO = "p_estado";
	private static String PARAM_DET_CODOC = "p_codoc";
	
	private static String PARAM_DET_GUIAITEM_CODITEM = "p_coditem";
	
	private static String PARAM_ITEM_CODITEM = "p_coditem";
	private static String PARAM_ITEM_CODITEM_SALIDA = "p_coditem_salida";
	private static String PARAM_ITEM_CODPRODUCTO = "p_codproducto";
	private static String PARAM_ITEM_CODIFICACION = "p_codificacion"; 
	private static String PARAM_ITEM_CODPROVEEDOR = "p_codproveedor"; 
	private static String PARAM_ITEM_ORIGEN = "p_origen"; 
	private static String PARAM_ITEM_PROPIEDADES = "p_propiedades";
	private static String PARAM_ITEM_PRECIOCOMPRA = "p_preciocompra"; 
	private static String PARAM_ITEM_CODMONEDA = "p_codmoneda"; 
	private static String PARAM_ITEM_CODTIENDA = "p_codtienda";
	private static String PARAM_ITEM_CODOC = "p_codoc"; 
	private static String PARAM_ITEM_NROLINEA = "p_nrolinea";
	private static String PARAM_ITEM_ESTADO = "p_estado";
	private static String PARAM_ITEM_INCIDENCIAS = "p_incidencias";
	
	private static String PARAM_ITEM_CODITEMUNION = "p_coditemunion";
	private static String PARAM_ITEM_UNIONITEM = "p_unionitem";
	
	private static String PARAM_BULTO_CODGUIA = "p_codguia";
	private static String PARAM_BULTO_CODBULTO = "p_codbulto";
	private static String PARAM_BULTO_SSCC = "p_sscc";
	private static String PARAM_BULTO_TOTALITEMS = "p_totalitems";
	private static String PARAM_BULTO_SSCCPADRE = "p_ssccpadre";
	private static String PARAM_BULTO_CODUSUARIO = "p_codusuario";
	private static String PARAM_BULTO_ESTADO = "p_estado";
	private static String PARAM_BULTO_CODTIENDA = "p_codtienda";
	
	private static String PARAM_ITEM_CODCOMPONENTE = "p_codcomponente";
	
	private static String PARAM_CODCLIENTE = "p_codcliente";
	
	// Parametros de Salida
	
	private static String CODGUIA = "CODGUIA";
	private static String CODMANTENIMIENTO = "CODMANTENIMIENTO"; 
	private static String CODPRESTAMO = "CODPRESTAMO";
	private static String CODSOLICITUD = "CODSOLICITUD";
	private static String CODTIENDADESTINO = "CODTIENDADESTINO"; 
	private static String CODTIENDAORIGEN = "CODTIENDAORIGEN";
	private static String CODTIPOGUIA = "CODTIPOGUIA"; 
	private static String CODTRANSPORTE ="CODTRANSPORTE"; 
	private static String CODVENTA ="CODVENTA"; 
	private static String ESTADO = "ESTADO"; 
	private static String FECHAEMISION = "FECHAEMISION"; 
	private static String FECHARECEPCION = "FECHARECEPCION"; 
	private static String FECHAREGISTRO = "FECHAREGISTRO";
	private static String NUMERO = "NUMERO"; 
	private static String SERIE = "SERIE";
	private static String NOMBRETIENDADESTINO = "NOMBRETIENDADESTINO";
	private static String NOMBRETIENDAORIGEN = "NOMBRETIENDAORIGEN";
	private static String DIRECCIONTIENDADESTINO = "DIRECCIONTIENDADESTINO";
	private static String DISTRITOTIENDADESTINO = "DISTRITOTIENDADESTINO";
	private static String DIRECCIONTIENDAORIGEN = "DIRECCIONTIENDAORIGEN";
	private static String DISTRITOTIENDAORIGEN = "DISTRITOTIENDAORIGEN";
	private static String TIPOGUIA = "TIPOGUIA";
	
	private static String ORDENCOMPRA = "CODOC";
	private static String CONTAR = "CONTAR";
	
	private static String DET_NROLINEA = "NROLINEA";
	private static String DET_CODPRODUCTO = "CODPRODUCTO";
	private static String DET_CODPRODUCTOPROVEEDOR = "CODPRODUCTOPROVEEDOR";
	private static String DET_NOMPRODUCTO = "NOMPRODUCTO";
	private static String DET_COMPPRODUCTO = "COMPPRODUCTO";
	private static String DET_CODNIVELPROD = "CODNIVELPROD";
	private static String DET_CODNIVELTIPO = "CODNIVELTIPO";
	private static String DET_CODNIVELMATERIAL = "CODNIVELMATERIAL";
	private static String DET_CODNIVELCOLOR = "CODNIVELCOLOR";
	private static String DET_NIVELPRODUCTODESCRIPCION = "NIVELPRODUCTODESCRIPCION";
	private static String DET_TIPODESCRIPCION = "TIPODESCRIPCION";
	private static String DET_MATERIALDESCRIPCION = "MATERIALDESCRIPCION";
	private static String DET_COLORDESCRIPCION = "COLORDESCRIPCION";
	private static String DET_UNIDADMEDIDA = "UNIDADMEDIDA";
	private static String DET_CANTIDAD = "CANTIDAD";
	
	private static String BULTO_CODBULTO = "CODBULTO";
	private static String BULTO_SSCC = "SSCC";
	
	private static String ITEM_CODITEM = "CODITEM";
	private static String ITEM_CODIFICACION = "CODIFICACION";
	private static String ITEM_PRECIOCOMPRA = "PRECIOCOMPRA";
	private static String ITEM_CODMONEDA = "CODMONEDA";
	private static String ITEM_CODTIENDA = "CODTIENDA";
	
	private static String PRESTAMO_CODCLIENTE = "CODCLIENTE";
	private static String PRESTAMO_CODUSUARIO = "CODUSUARIO";
	private static String PRESTAMO_ESTADO = "ESTADO";
	private static String PRESTAMO_CODTIENDA = "CODTIENDA";
	private static String PRESTAMO_FECHAREGISTRO = "FECHAREGISTRO";
    private static String PRESTAMO_NOMBRETIENDA = "NOMBRETIENDA";
    private static String PRESTAMO_TIPODOCUMENTO = "TIPODOCUMENTO";
    private static String PRESTAMO_PERIODOXDIAS = "PERIODOXDIAS";
    private static String PRESTAMO_FECHAINICIO = "FECHAINICIO";
    private static String PRESTAMO_FECHAFIN = "FECHAFIN";
    private static String PRESTAMO_CODDISENIADOR = "CODDISENIADOR";
    private static String PRESTAMO_DISENIADORNOMBRESYAPELLIDOS = "DISNOMBRESYAPELLIDOS";
	
    private static String CLIENTE_NRODOCUMENTO = "NRODOCUMENTO";
	private static String CLIENTE_RAZONSOCIAL = "RAZONSOCIAL";
	private static String CLIENTE_DIRECCION = "DIRECCION";
	
	private static String USUARIO_NOMBRESYAPELLIDOS = "NOMBRESYAPELLIDOS";
    
	private static String LISTADO = "LISTADO";
	private static String LISTADO_LINEAS = "LISTADO_LINEAS";
	private static String LISTADO_LINEAS_ITEM = "LISTADO_LINEAS_ITEM";
	private static String LISTADO_BULTOS = "LISTADO_BULTO";
	
	private static String TOTAL_FILAS_AFECTADAS = "#update-count-1";
	
	private JdbcTemplate jdbcTemplate;

	@Autowired
    public void setDataSource(DataSource dataSource)
    {
        this.jdbcTemplate = new JdbcTemplate(dataSource);
    }
	
	@Override
	public boolean registrarGuia(Guia guia){
		logger.info("registrarGuia");
		
		int resultado = 0;
		
		// Instanciando variable para llamado de SP
	    SimpleJdbcCall llamarSP = new SimpleJdbcCall(jdbcTemplate).withProcedureName(SP_REGISTRAR_GUIA);

	    // Estableciendo parametros de entrada al SP
	    SqlParameterSource parametros = new MapSqlParameterSource()
	    								.addValue(PARAM_CODTIENDADESTINO, (guia.getTiendaDestino()==null?null:guia.getTiendaDestino().getCodigo()))
	    								.addValue(PARAM_CODTIENDAORIGEN, (guia.getTiendaOrigen()==null?null:guia.getTiendaOrigen().getCodigo()))
	    								.addValue(PARAM_CODTIPOGUIA, guia.getTipoGuia().getCodigo())
	    								.addValue(PARAM_NUMERO, guia.getNumero())
	    								.addValue(PARAM_SERIE, guia.getSerie())
	    								.addValue(PARAM_CODTRANSPORTE, guia.getTransporte().getCodTransporte())
	    								.addValue(PARAM_CODVENTA, (guia.getVenta()==null?null:guia.getVenta().getCodVenta()))
	    								.addValue(PARAM_CODPRESTAMO, (guia.getPrestamo()==null?null:guia.getPrestamo().getCodPrestamo()))
	    								.addValue(PARAM_CODMANTENIMIENTO, (guia.getMantenimiento()==null?null:guia.getMantenimiento().getCodMantenimiento()))
	    								.addValue(PARAM_CODSOLICITUD, (guia.getSolicitud()==null?null:guia.getSolicitud().getCodSolicitud()))
	    								.addValue(PARAM_FECHAEMISION, guia.getFechaEmision())
	    								.addValue(PARAM_FECHARECEPCION, guia.getFechaRecepcion())
	    								.addValue(PARAM_ESTADO, guia.getEstado());
	      
	    // Establecer parametros y ejecutar SP
	    Map<String,Object> data = llamarSP.execute(parametros);
	    
	    // Obteniendo el total de filas afectadas al ejecutar SP
	    resultado += (Integer) data.get(TOTAL_FILAS_AFECTADAS);
	    
	    logger.debug("codigo generado:" + data.get(PARAM_CODGUIA));

	    // Obteniendo codigo de guia generada
	    int codigoGuia = (Integer)data.get(PARAM_CODGUIA);

	    // Estableciendo codigo de guia generada
	    guia.setCodGuia(codigoGuia);
	    
	    // ==== Registro guia - ordencompra ====
	    resultado += registrarGuiaOrdenCompra(guia);
	    
	    // ==== Registro detalle guia, item y detalleItem ====
	    resultado += registrarGuiaDetalle(guia, false);
	    
	    return resultado > 0;
	}
	
	@Override
	public boolean registrarGuiaImportacion(Guia guia){
		logger.info("registrarGuiaImportacion");
		
		int resultado = 0;
		
		// Instanciando variable para llamado de SP
	    SimpleJdbcCall llamarSP = new SimpleJdbcCall(jdbcTemplate).withProcedureName(SP_REGISTRAR_GUIA);

	    // Estableciendo parametros de entrada al SP
	    SqlParameterSource parametros = new MapSqlParameterSource()
	    								.addValue(PARAM_CODTIENDADESTINO, (guia.getTiendaDestino()==null?null:guia.getTiendaDestino().getCodigo()))
	    								.addValue(PARAM_CODTIENDAORIGEN, (guia.getTiendaOrigen()==null?null:guia.getTiendaOrigen().getCodigo()))
	    								.addValue(PARAM_CODTIPOGUIA, guia.getTipoGuia().getCodigo())
	    								.addValue(PARAM_NUMERO, guia.getNumero())
	    								.addValue(PARAM_SERIE, guia.getSerie())
	    								.addValue(PARAM_CODTRANSPORTE, guia.getTransporte()==null?null:guia.getTransporte().getCodTransporte())
	    								.addValue(PARAM_CODVENTA, (guia.getVenta()==null?null:guia.getVenta().getCodVenta()))
	    								.addValue(PARAM_CODPRESTAMO, (guia.getPrestamo()==null?null:guia.getPrestamo().getCodPrestamo()))
	    								.addValue(PARAM_CODMANTENIMIENTO, (guia.getMantenimiento()==null?null:guia.getMantenimiento().getCodMantenimiento()))
	    								.addValue(PARAM_CODSOLICITUD, (guia.getSolicitud()==null?null:guia.getSolicitud().getCodSolicitud()))
	    								.addValue(PARAM_FECHAEMISION, guia.getFechaEmision())
	    								.addValue(PARAM_FECHARECEPCION, guia.getFechaRecepcion())
	    								.addValue(PARAM_ESTADO, guia.getEstado());
	      
	    // Establecer parametros y ejecutar SP
	    Map<String,Object> data = llamarSP.execute(parametros);
	    
	    // Obteniendo el total de filas afectadas al ejecutar SP
	    resultado += (Integer) data.get(TOTAL_FILAS_AFECTADAS);
	    
	    logger.debug("codigo generado:" + data.get(PARAM_CODGUIA));

	    // Obteniendo codigo de guia generada
	    int codigoGuia = (Integer)data.get(PARAM_CODGUIA);

	    // Estableciendo codigo de guia generada
	    guia.setCodGuia(codigoGuia);
	    
	    // ==== Registro guia - ordencompra ====
	    //resultado += registrarGuiaOrdenCompra(guia);
	    
	    // ==== Registro bulto, item, itemComponente y detalle bulto====
	    //resultado += registrarGuiaDetalleBulto(guia);
	    
	    return resultado > 0;
	}
	
	@Override
	public boolean registrarGuiaDocumento(Guia guia){
		logger.info("registrarGuiaDocumento");
		
		int resultado = 0;
		
		// Instanciando variable para llamado de SP
	    SimpleJdbcCall llamarSP = new SimpleJdbcCall(jdbcTemplate).withProcedureName(SP_REGISTRAR_GUIA);

	    // Estableciendo parametros de entrada al SP
	    SqlParameterSource parametros = new MapSqlParameterSource()
	    								.addValue(PARAM_CODTIENDADESTINO, (guia.getTiendaDestino()==null?null:guia.getTiendaDestino().getCodigo()))
	    								.addValue(PARAM_CODTIENDAORIGEN, (guia.getTiendaOrigen()==null?null:guia.getTiendaOrigen().getCodigo()))
	    								.addValue(PARAM_CODTIPOGUIA, guia.getTipoGuia().getCodigo())
	    								.addValue(PARAM_NUMERO, guia.getNumero())
	    								.addValue(PARAM_SERIE, guia.getSerie())
	    								.addValue(PARAM_CODTRANSPORTE, guia.getTransporte()==null?null:guia.getTransporte().getCodTransporte())
	    								.addValue(PARAM_CODVENTA, (guia.getVenta()==null?null:guia.getVenta().getCodVenta()))
	    								.addValue(PARAM_CODPRESTAMO, (guia.getPrestamo()==null?null:guia.getPrestamo().getCodPrestamo()))
	    								.addValue(PARAM_CODMANTENIMIENTO, (guia.getMantenimiento()==null?null:guia.getMantenimiento().getCodMantenimiento()))
	    								.addValue(PARAM_CODSOLICITUD, (guia.getSolicitud()==null?null:guia.getSolicitud().getCodSolicitud()))
	    								.addValue(PARAM_FECHAEMISION, guia.getFechaEmision())
	    								.addValue(PARAM_FECHARECEPCION, guia.getFechaRecepcion())
	    								.addValue(PARAM_ESTADO, guia.getEstado());
	      
	    // Establecer parametros y ejecutar SP
	    Map<String,Object> data = llamarSP.execute(parametros);
	    
	    // Obteniendo el total de filas afectadas al ejecutar SP
	    resultado += (Integer) data.get(TOTAL_FILAS_AFECTADAS);
	    
	    logger.debug("codigo generado:" + data.get(PARAM_CODGUIA));

	    // Obteniendo codigo de guia generada
	    int codigoGuia = (Integer)data.get(PARAM_CODGUIA);

	    // Estableciendo codigo de guia generada
	    guia.setCodGuia(codigoGuia);
	       
	    // ==== Registro detalle guia, item y detalleItem ====
	    resultado += registrarGuiaDetalle(guia, true);
	    
	    return resultado > 0;
	}
	
	public int registrarGuiaOrdenCompra(Guia guia){
		logger.info("registrarGuiaOrdenCompra");
        
		// Instanciando variable para llamado de SP Eliminar items registrados en transferencia pasadas
	    SimpleJdbcCall llamarSPLimpiarGuiaOrdenCompra = new SimpleJdbcCall(jdbcTemplate).withProcedureName(SP_LIMPIAR_GUIA_ORDENCOMPRA);
	    // Agregar parametro codigo de cliente
	    llamarSPLimpiarGuiaOrdenCompra.execute(new MapSqlParameterSource()
										     .addValue(PARAM_CODGUIA, guia.getCodGuia()));
	    
		int totalRegistrosAfectado = 0;
		
		// Obteniendo lista de ordenes de compra a agregar
	    ListaOrdenCompra listaOrdenCompra = guia.getListaOrdenCompra();
	    
	    // Si existen ordenes de compras asociado a la guia
	    if(listaOrdenCompra != null && listaOrdenCompra.getLista() != null) {
	    	// Instanciando variable para llamado de SP
		    SimpleJdbcCall llamarSPOrdenesCompra = new SimpleJdbcCall(jdbcTemplate).withProcedureName(SP_REGISTRAR_GUIA_ORDENCOMPRA);
	
		    for (OrdenCompra ordenCompra : listaOrdenCompra.getLista()){
			    // Estableciendo parametros de entrada al SP
			    SqlParameterSource parametrosDetalle = new MapSqlParameterSource()
						    								.addValue(PARAM_CODGUIA, guia.getCodGuia())
						    								.addValue(PARAM_GUIAOC_CODOC, ordenCompra.getCodOC());
			    
			    // Establecer parametros y ejecutar SP
			    Map<String,Object> dataOrdenes = llamarSPOrdenesCompra.execute(parametrosDetalle);
			    
			    // Obteniendo el total de filas afectadas al ejecutar SP
			    totalRegistrosAfectado += (Integer) dataOrdenes.get(TOTAL_FILAS_AFECTADAS);
			    
			    // ==== Actualizar Estado OrdenCompra ====
			    totalRegistrosAfectado += actualizarEstadoOrdenCompra(ordenCompra);
			    // ==== Actualizar detalle orden compra ===
			    totalRegistrosAfectado += modificarDetalleOrdenCompra(ordenCompra);
		    }
	    }
		
		return totalRegistrosAfectado;
	}
	
	private int actualizarEstadoOrdenCompra(OrdenCompra ordenCompra){
		logger.info("actualizarOrdenCompra");
		
		// Instanciando variable para llamado de SP
	    SimpleJdbcCall llamarSP = new SimpleJdbcCall(jdbcTemplate).withProcedureName(SP_ACTUALIZAR_ESTADO_ORDENCOMPRA);

	    // Estableciendo parametros de entrada al SP
	    SqlParameterSource parametros = new MapSqlParameterSource()
	    								.addValue(PARAM_GUIAOC_CODOC, ordenCompra.getCodOC())
	    								.addValue(PARAM_GUIAOC_ESTADO, ordenCompra.getEstado());
	    
	    // Establecer parametros y ejecutar SP
	    Map<String,Object> data = llamarSP.execute(parametros);
	    
	    // Obteniendo el total de filas afectadas al ejecutar SP
	    int totalRegistrosAfectado = (Integer) data.get(TOTAL_FILAS_AFECTADAS);
	        
	    return totalRegistrosAfectado;
	}
	
	private int modificarDetalleOrdenCompra(OrdenCompra ordenCompra) {
		logger.info("modificarDetalleOrdenCompra");
		
		int totalRegistrosAfectado = 0;
		// Instanciando variable para llamado de SP
		SimpleJdbcCall llamarSP = new SimpleJdbcCall(jdbcTemplate)
				.withProcedureName(SP_MODIFICAR_DET_ORDENCOMPRA);

		for (LineaOrdenCompra lineaOrdenCompra : ordenCompra.getListaLineaOrdenCompra().getLista()) {

			// Estableciendo parametros de entrada al SP
			SqlParameterSource parametros = new MapSqlParameterSource()
					.addValue(PARAM_DET_CODOC, lineaOrdenCompra.getCodOC())
					.addValue(PARAM_DET_CODPRODUCTO, lineaOrdenCompra.getProducto().getCodigo())
					.addValue(PARAM_DET_CANTIDADRECIBIDA, lineaOrdenCompra.getCantidadRecibida())
					.addValue(PARAM_DET_ESTADO, lineaOrdenCompra.getEstado());

			// Establecer parametros y ejecutar SP
			Map<String, Object> data = llamarSP.execute(parametros);

			// Obteniendo el total de filas afectadas al ejecutar SP
			totalRegistrosAfectado = (Integer) data.get(TOTAL_FILAS_AFECTADAS);
		}
		return totalRegistrosAfectado;
	}
	
	public int registrarGuiaDetalle(Guia guia, boolean actualizarItem){
		logger.info("registrarGuiaDetalle");
		
		int totalRegistrosAfectado = 0;
		
		// Obteniendo lista de lineas de la guia a agregar
	    ListaLineaGuia listaLineaGuia = guia.getListaLineaGuia();
	    
	    // Instanciando variable para llamado de SP
	    SimpleJdbcCall llamarSPLineas = new SimpleJdbcCall(jdbcTemplate).withProcedureName(SP_REGISTRAR_DET_GUIA);
        
	    int iNroLinea = 1;
	    for (LineaGuia lineaGuia : listaLineaGuia.getLista()){
		    // Estableciendo parametros de entrada al SP
		    SqlParameterSource parametrosDetalle = new MapSqlParameterSource()
					    								.addValue(PARAM_CODGUIA, guia.getCodGuia())
					    								.addValue(PARAM_DET_NROLINEA, iNroLinea)
					    								.addValue(PARAM_DET_CODPRODUCTO , lineaGuia.getProducto().getCodigo())
					    								.addValue(PARAM_DET_CANTIDAD, lineaGuia.getCantidad());
		    
		    
		    
		    // Establecer parametros y ejecutar SP
		    Map<String,Object> dataDetalle = llamarSPLineas.execute(parametrosDetalle);
		    
		    // Obteniendo el total de filas afectadas al ejecutar SP
		    totalRegistrosAfectado += (Integer) dataDetalle.get(TOTAL_FILAS_AFECTADAS);
		    
		    // Obteniendo numero de linea
		    int codigoNroLinea = (Integer)dataDetalle.get(PARAM_DET_NROLINEA_REG);
		    
		    // Estableciendo codgio de guia
		    lineaGuia.setCodGuia(guia.getCodGuia());
		    
		    // Estableciendo codigo de numero de linea generada
		    lineaGuia.setNumeroLinea(codigoNroLinea);
		    
		    // ==== Registro de lineas de la Guia - Item ====
		    totalRegistrosAfectado += registrarGuiaDetalleItem(lineaGuia, actualizarItem);
		    
		    iNroLinea++;
	    }
	    
	    return totalRegistrosAfectado;
	}
	
	private int registrarGuiaDetalleItem(LineaGuia lineaGuia, boolean actualizarItem){
		logger.info("registrarGuiaDetalleItem");
		
		int totalRegistrosAfectado = 0;
		
		// Obteniendo lista de lineas de la guia a agregar
	    ListaLineaGuiaItem listaLineaGuiaItem = lineaGuia.getListaLineaGuiaItem();
	    
	    // Instanciando variable para llamado de SP
	    SimpleJdbcCall llamarSPLineasItem = new SimpleJdbcCall(jdbcTemplate).withProcedureName(SP_REGISTRAR_DET_GUIA_ITEM);
	    
	    for (LineaGuiaItem lineaGuiaItem : listaLineaGuiaItem.getLista()){
	    	
	    	if(actualizarItem){
	    		// ==== Actualizar estado de Items ====
		    	totalRegistrosAfectado += actualizarEstadoItem(lineaGuiaItem.getItem());
	    	}else{
	    		// ==== Registro de Items ====
		    	totalRegistrosAfectado += registrarItem(lineaGuiaItem.getItem());
	    	}
	    	
		    // Estableciendo parametros de entrada al SP
		    SqlParameterSource parametrosDetalleItem = new MapSqlParameterSource()
					    								.addValue(PARAM_CODGUIA, lineaGuia.getCodGuia())
					    								.addValue(PARAM_DET_NROLINEA, lineaGuia.getNumeroLinea())
					    								.addValue(PARAM_DET_GUIAITEM_CODITEM, lineaGuiaItem.getItem().getCodItem());
		    
		    // Establecer parametros y ejecutar SP
		    Map<String,Object> dataDetalleItem = llamarSPLineasItem.execute(parametrosDetalleItem);
		    
		    // Obteniendo el total de filas afectadas al ejecutar SP
		    totalRegistrosAfectado += (Integer) dataDetalleItem.get(TOTAL_FILAS_AFECTADAS);
	    }
	    
		return totalRegistrosAfectado;
	}
	
	private int registrarItem(Item item){
		logger.info("registrarItem");
		
		// Instanciando variable para llamado de SP
	    SimpleJdbcCall llamarSP = new SimpleJdbcCall(jdbcTemplate).withProcedureName(SP_REGISTRAR_ITEM);

	    // Estableciendo parametros de entrada al SP
	    SqlParameterSource parametros = new MapSqlParameterSource()
	                                    .addValue(PARAM_ITEM_CODITEM, item.getCodItem())
	    								.addValue(PARAM_ITEM_CODPRODUCTO, item.getProducto().getCodigo())
	    								.addValue(PARAM_ITEM_CODIFICACION, item.getCodificacion())
	    								.addValue(PARAM_ITEM_CODPROVEEDOR , item.getProveedor().getCodProveedor())
	    								.addValue(PARAM_ITEM_ORIGEN, item.getOrigen())
	    								.addValue(PARAM_ITEM_PROPIEDADES, item.getPropiedades())
	    								.addValue(PARAM_ITEM_PRECIOCOMPRA, item.getPrecioCompra())
	    								.addValue(PARAM_ITEM_CODMONEDA, item.getMoneda().getCodigo())
	    								.addValue(PARAM_ITEM_CODOC, item.getLineaOrdenCompra().getCodOC())
	    								.addValue(PARAM_ITEM_NROLINEA, item.getLineaOrdenCompra().getNumeroLinea())
	    								.addValue(PARAM_ITEM_CODTIENDA, item.getTienda().getCodigo())
	    								.addValue(PARAM_ITEM_INCIDENCIAS, item.getIncidencias())
	    								.addValue(PARAM_ITEM_ESTADO, item.getEstado());
	    
	    // Establecer parametros y ejecutar SP
	    Map<String,Object> data = llamarSP.execute(parametros);
	    
	    // Obteniendo el total de filas afectadas al ejecutar SP
	    int totalRegistrosAfectado = (Integer) data.get(TOTAL_FILAS_AFECTADAS);
	    
	    // Obteniendo codigo de item
	    int codigoItem = (Integer)data.get(PARAM_ITEM_CODITEM_SALIDA);

	    // Estableciendo codigo de item
	    item.setCodItem(codigoItem);
	    
	    // ==== Registro de ItemsComponentes ====
	    totalRegistrosAfectado += registrarItemComponente(item);
	    
	    return totalRegistrosAfectado;
	}

	public int registrarGuiaDetalleBulto(Guia guia){
		logger.info("registrarGuiaDetalleBulto");
		
		int totalRegistrosAfectado = 0;
		Bulto bulto = null;
		
		// Obteniendo lista de lineas a agregar
	    ListaLineaGuiaBulto listaLineaGuiaBulto = guia.getListaLineaGuiaBulto();
	    
	    // Instanciando variable para llamado de SP
	    SimpleJdbcCall llamarSP = new SimpleJdbcCall(jdbcTemplate).withProcedureName(SP_REGISTRAR_BULTO);
	    
	    for (LineaGuiaBulto lineaGuiabulto : listaLineaGuiaBulto.getLista()){
	    	// Obteniendo el bulto asociado a la linea
	    	bulto = lineaGuiabulto.getBulto();
	    	
	    	// Estableciendo codigo de guia al bulto
	    	bulto.setCodGuia(guia.getCodGuia());
	    	
	    	// Estableciendo parametros de entrada al SP
		    SqlParameterSource parametros = new MapSqlParameterSource()
		    								.addValue(PARAM_BULTO_CODGUIA, bulto.getCodGuia())
		    								.addValue(PARAM_BULTO_SSCC, bulto.getSSCC())
		    								.addValue(PARAM_BULTO_TOTALITEMS , bulto.getTotalItems())
		    								.addValue(PARAM_BULTO_SSCCPADRE, bulto.getSSCCPadre())
		    								.addValue(PARAM_BULTO_CODUSUARIO, bulto.getUsuario().getCodUsuario())
		    								.addValue(PARAM_BULTO_CODTIENDA, bulto.getTienda().getCodigo())
		    								.addValue(PARAM_BULTO_ESTADO, bulto.getEstado());
		    
		    // Establecer parametros y ejecutar SP
		    Map<String,Object> data = llamarSP.execute(parametros);
		    
		    // Obteniendo el total de filas afectadas al ejecutar SP
		    totalRegistrosAfectado += (Integer) data.get(TOTAL_FILAS_AFECTADAS);
		    
		    // Obteniendo codigo de bulto
		    int codigoBulto = (Integer)data.get(PARAM_BULTO_CODBULTO);

		    // Estableciendo codigo de bulto
		    bulto.setCodBulto(codigoBulto);
		    
		    // ==== Registro de Bulto en Guia ====
		    totalRegistrosAfectado += registrarBultoGuia(bulto);
		    // ==== Registro de Items ====
		    totalRegistrosAfectado += registrarBultoItem(bulto);
		    
	    }
	    
		return totalRegistrosAfectado;
	}
	
	//DESPACHO BULTOS TIENDA
	@Override
	public boolean registrarGuiaDocumentoBulto(Guia guia){
		logger.info("registrarGuiaDocumentoBulto");
		
		int resultado = 0;
		
		// Instanciando variable para llamado de SP
	    SimpleJdbcCall llamarSP = new SimpleJdbcCall(jdbcTemplate).withProcedureName(SP_REGISTRAR_GUIA);

	    // Estableciendo parametros de entrada al SP
	    SqlParameterSource parametros = new MapSqlParameterSource()
	    								.addValue(PARAM_CODTIENDADESTINO, (guia.getTiendaDestino()==null?null:guia.getTiendaDestino().getCodigo()))
	    								.addValue(PARAM_CODTIENDAORIGEN, (guia.getTiendaOrigen()==null?null:guia.getTiendaOrigen().getCodigo()))
	    								.addValue(PARAM_CODTIPOGUIA, guia.getTipoGuia().getCodigo())
	    								.addValue(PARAM_NUMERO, guia.getNumero())
	    								.addValue(PARAM_SERIE, guia.getSerie())
	    								.addValue(PARAM_CODTRANSPORTE, guia.getTransporte()==null?null:guia.getTransporte().getCodTransporte())
	    								.addValue(PARAM_CODVENTA, (guia.getVenta()==null?null:guia.getVenta().getCodVenta()))
	    								.addValue(PARAM_CODPRESTAMO, (guia.getPrestamo()==null?null:guia.getPrestamo().getCodPrestamo()))
	    								.addValue(PARAM_CODMANTENIMIENTO, (guia.getMantenimiento()==null?null:guia.getMantenimiento().getCodMantenimiento()))
	    								.addValue(PARAM_CODSOLICITUD, (guia.getSolicitud()==null?null:guia.getSolicitud().getCodSolicitud()))
	    								.addValue(PARAM_FECHAEMISION, guia.getFechaEmision())
	    								.addValue(PARAM_FECHARECEPCION, guia.getFechaRecepcion())
	    								.addValue(PARAM_ESTADO, guia.getEstado());
	      
	    // Establecer parametros y ejecutar SP
	    Map<String,Object> data = llamarSP.execute(parametros);
	    
	    // Obteniendo el total de filas afectadas al ejecutar SP
	    resultado += (Integer) data.get(TOTAL_FILAS_AFECTADAS);
	    
	    logger.debug("codigo generado:" + data.get(PARAM_CODGUIA));

	    // Obteniendo codigo de guia generada
	    int codigoGuia = (Integer)data.get(PARAM_CODGUIA);

	    // Estableciendo codigo de guia generada
	    guia.setCodGuia(codigoGuia);
	    
	    return resultado > 0;
	}
	
	public boolean registrarGuiaBultoDetalle(LineaGuiaBulto lineaGuiaBulto) {
		logger.info("registrarBultoGuiaDetalle");
		
		int resultado = 0;
		
		// Instanciando variable para llamado de SP
	    SimpleJdbcCall llamarSP = new SimpleJdbcCall(jdbcTemplate)
	    							  .withProcedureName(SP_REGISTRAR_GUIA_BULTO);

	    // Estableciendo parametros de entrada al SP
	    SqlParameterSource parametros = new MapSqlParameterSource()
	    									.addValue(PARAM_BULTO_CODGUIA, lineaGuiaBulto.getCodGuia())
	    									.addValue(PARAM_BULTO_CODBULTO, lineaGuiaBulto.getBulto().getCodBulto());
	    
	    // Establecer parametros y ejecutar SP
	    Map<String,Object> data = llamarSP.execute(parametros);
	    
	    // Obteniendo el total de filas afectadas al ejecutar SP
	    resultado = (Integer) data.get(TOTAL_FILAS_AFECTADAS);
	        
	    return resultado > 0;
		
	}

	@Override
	public Guia obtenerGuiaDocumentoBulto(Guia guia){
		logger.info("obtenerGuiaDocumentoBulto");

			// Instanciando variable para llamado de SP
		    SimpleJdbcCall llamarSP = new SimpleJdbcCall(jdbcTemplate).withProcedureName(SP_OBTENER_GUIA_BULTO).
		    						  returningResultSet(LISTADO, new RowMapper<Guia>(){
										@Override
										public Guia mapRow(final ResultSet rs, final int numRow) throws SQLException
									    {
									        final Guia guia = new Guia();
									        guia.setCodGuia(rs.getInt(CODGUIA));
									        guia.setSerie(rs.getString(SERIE));
									        guia.setNumero(rs.getString(NUMERO));
									        
									        Mantenimiento mantenimiento =  new Mantenimiento();
									        mantenimiento.setCodMantenimiento(rs.getInt(CODMANTENIMIENTO));
									        guia.setMantenimiento(mantenimiento);
									        
									        Prestamo prestamo = new Prestamo();
									        prestamo.setCodPrestamo(rs.getInt(CODPRESTAMO));
									        guia.setPrestamo(prestamo);
									        
									        Solicitud solicitud = new Solicitud();
									        solicitud.setCodSolicitud(rs.getInt(CODSOLICITUD));
									        guia.setSolicitud(solicitud);
									        
									        Transporte transporte = new Transporte();
									        transporte.setCodTransporte(rs.getInt(CODTRANSPORTE));
									        guia.setTransporte(transporte);
									        
									        Venta venta = new Venta();
									        venta.setCodVenta(rs.getInt(CODVENTA));
									        guia.setVenta(venta);
									        
									        TipoGuia tipoGuia =  new TipoGuia();
									        tipoGuia.setCodigo(rs.getInt(CODTIPOGUIA));
									        tipoGuia.setDescripcion(rs.getString(TIPOGUIA));
									        guia.setTipoGuia(tipoGuia);
									        
									        guia.setEstado(rs.getString(ESTADO));
									        guia.setFechaRegistro(rs.getDate(FECHAREGISTRO)==null?null:rs.getDate(FECHAREGISTRO).toString());
									        guia.setFechaEmision(rs.getDate(FECHAEMISION)==null?null:rs.getDate(FECHAEMISION).toString());
									        guia.setFechaRecepcion(rs.getDate(FECHARECEPCION)==null?null:rs.getDate(FECHARECEPCION).toString());
									        
									        Tienda tiendaDestino= new Tienda();
									        tiendaDestino.setCodigo(rs.getInt(CODTIENDADESTINO));
									        tiendaDestino.setNombre(rs.getString(NOMBRETIENDADESTINO));
									        tiendaDestino.setDireccion(rs.getString(DIRECCIONTIENDADESTINO));
									        tiendaDestino.setDistrito(rs.getString(DISTRITOTIENDADESTINO));
									        guia.setTiendaDestino(tiendaDestino);
									       
									        Tienda tiendaOrigen= new Tienda();
									        tiendaOrigen.setCodigo(rs.getInt(CODTIENDAORIGEN));
									        tiendaOrigen.setNombre(rs.getString(NOMBRETIENDAORIGEN));
									        tiendaOrigen.setDireccion(rs.getString(DIRECCIONTIENDAORIGEN));
									        tiendaOrigen.setDistrito(rs.getString(DISTRITOTIENDAORIGEN));
									        guia.setTiendaOrigen(tiendaOrigen);
									        
									        return guia;
									    }
		    						  }
									)
									.returningResultSet(LISTADO_LINEAS, new RowMapper<LineaGuia>(){
										@Override
										public LineaGuia mapRow(final ResultSet rs, final int numRow) throws SQLException
									    {
									        final LineaGuia lineaGuia = new LineaGuia();
									        lineaGuia.setNumeroLinea(rs.getInt(DET_NROLINEA));
									        lineaGuia.setCodGuia(rs.getInt(CODGUIA));
									        
									        Producto producto = new Producto();
									        producto.setCodigo(rs.getInt(DET_CODPRODUCTO));
									        producto.setDescripcion(rs.getString(DET_NOMPRODUCTO));
									        producto.setCodProductoProveedor(rs.getString(DET_CODPRODUCTOPROVEEDOR));
									        producto.setUnidadMedida(rs.getString(DET_UNIDADMEDIDA));
									        
									        NivelProducto nivelProducto = new NivelProducto();
									        nivelProducto.setCodigo(rs.getInt(DET_CODNIVELPROD));
									        nivelProducto.setDescripcion(rs.getString(DET_NIVELPRODUCTODESCRIPCION));
									        producto.setNivelProducto(nivelProducto);
									        
									        NivelColor nivelColor = new NivelColor();
									        nivelColor.setCodigo(rs.getInt(DET_CODNIVELCOLOR));
									        nivelColor.setCodNivelProducto(rs.getInt(DET_CODNIVELPROD));
									        nivelColor.setDescripcion(rs.getString(DET_COLORDESCRIPCION));
									        producto.setNivelColor(nivelColor);
									        
									        NivelTipo nivelTipo = new NivelTipo();
									        nivelTipo.setCodigo(rs.getInt(DET_CODNIVELTIPO));
									        nivelTipo.setCodNivelProducto(rs.getInt(DET_CODNIVELPROD));
									        nivelTipo.setDescripcion(rs.getString(DET_TIPODESCRIPCION));
									        producto.setNivelTipo(nivelTipo);
									        
									        NivelMaterial nivelMaterial = new NivelMaterial();
									        nivelMaterial.setCodigo(rs.getInt(DET_CODNIVELMATERIAL));
									        nivelMaterial.setCodNivelProducto(rs.getInt(DET_CODNIVELPROD));
									        nivelMaterial.setDescripcion(rs.getString(DET_MATERIALDESCRIPCION));
									        producto.setNivelMaterial(nivelMaterial);
									        
									        lineaGuia.setProducto(producto);
									        
									        lineaGuia.setCantidad(rs.getInt(DET_CANTIDAD));
									        
									        return lineaGuia;
									    }
		    						  })
		    						.returningResultSet(LISTADO_BULTOS, new RowMapper<LineaGuiaBulto>() {
    							    @Override
									public LineaGuiaBulto mapRow(final ResultSet rs, final int numRow) throws SQLException
								    {
								        final LineaGuiaBulto lineaGuiaBulto = new LineaGuiaBulto();
								        lineaGuiaBulto.setCodGuia(rs.getInt(CODGUIA));
								        
								        Bulto bulto = new Bulto();
								        bulto.setCodBulto(rs.getInt(BULTO_CODBULTO));
								        bulto.setSSCC(rs.getString(BULTO_SSCC));
								        lineaGuiaBulto.setBulto(bulto);
	
								        return lineaGuiaBulto;
								    }
								});

		    // Estableciendo parametros de entrada al SP
		    SqlParameterSource parametros = new MapSqlParameterSource()
		    								.addValue(PARAM_NUMERO, guia.getNumero())
		    								.addValue(PARAM_SERIE, guia.getSerie()); 

		    // Establecer parametros y ejecutar SP
	        Map<String,Object> data = llamarSP.execute(parametros);

	        // Obteniendo lista generada de ejecutar SP
			@SuppressWarnings("unchecked")
			List<Guia> listaGuia = (List<Guia>)data.get(LISTADO);
	        
			// Declarando objeto Guia Obtenido
	 		Guia GuiaObtenido = null;
	 		
	 		if (logger.isDebugEnabled() && listaGuia != null)
	        {
	            logger.debug("size=" + listaGuia.size());
	        }
			
	 		if (listaGuia != null && listaGuia.size()>0){
	 			// Obteniendo el primer elemento de la lista de Guia
	 			GuiaObtenido = listaGuia.get(0);
	 		
		        // Obteniendo lista de lineas generada de ejecutar SP
				@SuppressWarnings("unchecked")
				List<LineaGuia> listaLineaGuia = (List<LineaGuia>)data.get(LISTADO_LINEAS);
		        
				// Instanciando objeto ListaLineaGuia
				ListaLineaGuia listaLineaGuiaResultado = new ListaLineaGuia();
		        // Estableciendo resultado al objeto listaLineaGuiaResultado
				listaLineaGuiaResultado.setLista(listaLineaGuia);
		        
				// --------------------------------------------------------------------------------------------
				// Obteniendo lista de lineas-item generada de ejecutar SP
				@SuppressWarnings("unchecked")
				List<LineaGuiaBulto> listaLineaGuiaBulto = (List<LineaGuiaBulto>)data.get(LISTADO_BULTOS);
		        
				// Instanciando objeto ListaLineaSolicitudBulto
				ListaLineaGuiaBulto listaLineaGuiaBultoResultado = new ListaLineaGuiaBulto();
		        // Estableciendo resultado al objeto listaLineaSolicitudBultoResultado
				listaLineaGuiaBultoResultado.setLista(listaLineaGuiaBulto);
		        
				// Asignando lista de bultos al objeto solicitudObtenido creado
				GuiaObtenido.setListaLineaGuiaBulto(listaLineaGuiaBultoResultado);
				
		        if (logger.isDebugEnabled() && listaLineaGuiaBultoResultado != null)
		        {
		            logger.debug("sizeBultos=" + listaLineaGuiaBultoResultado.size());
		        }
	 		}

			return GuiaObtenido;
		}
	
	//FIN
	
	private int registrarBultoGuia(Bulto bulto){
		logger.info("registrarBultoGuia");
		
		int totalRegistrosAfectado = 0;
		
		// Instanciando variable para llamado de SP
	    SimpleJdbcCall llamarSP = new SimpleJdbcCall(jdbcTemplate).withProcedureName(SP_REGISTRAR_GUIA_BULTO);
	    
	    
	    	 // Estableciendo parametros de entrada al SP
		    SqlParameterSource parametros = new MapSqlParameterSource()
		    								.addValue(PARAM_BULTO_CODGUIA, bulto.getCodGuia())
		    								.addValue(PARAM_BULTO_CODBULTO, bulto.getCodBulto());
		    
		    // Establecer parametros y ejecutar SP
		    Map<String,Object> data = llamarSP.execute(parametros);
		    
		    // Obteniendo el total de filas afectadas al ejecutar SP
		    totalRegistrosAfectado += (Integer) data.get(TOTAL_FILAS_AFECTADAS);
		    
		return totalRegistrosAfectado;
	}
	
	private int registrarBultoItem(Bulto bulto){
		logger.info("registrarBultoItem");
		
		int totalRegistrosAfectado = 0;
		
		// Obteniendo lista a agregar
	    ListaItem listaItem = bulto.getListaItem();
	    
	    // Instanciando variable para llamado de SP
	    SimpleJdbcCall llamarSP = new SimpleJdbcCall(jdbcTemplate).withProcedureName(SP_REGISTRAR_ITEM);
	    
	    for (Item item : listaItem.getLista()){
	    	 // Estableciendo parametros de entrada al SP
		    SqlParameterSource parametros = new MapSqlParameterSource()
		                                    .addValue(PARAM_ITEM_CODITEM, item.getCodItem())
		    								.addValue(PARAM_ITEM_CODPRODUCTO, item.getProducto().getCodigo())
		    								.addValue(PARAM_ITEM_CODIFICACION, item.getCodificacion())
		    								.addValue(PARAM_ITEM_CODPROVEEDOR , item.getProveedor().getCodProveedor())
		    								.addValue(PARAM_ITEM_ORIGEN, item.getOrigen())
		    								.addValue(PARAM_ITEM_PROPIEDADES, item.getPropiedades())
		    								.addValue(PARAM_ITEM_PRECIOCOMPRA, item.getPrecioCompra())
		    								.addValue(PARAM_ITEM_CODMONEDA, item.getMoneda().getCodigo())
		    								.addValue(PARAM_ITEM_CODOC, item.getLineaOrdenCompra().getCodOC())
		    								.addValue(PARAM_ITEM_NROLINEA, item.getLineaOrdenCompra().getNumeroLinea())
		    								.addValue(PARAM_ITEM_CODTIENDA, item.getTienda().getCodigo())
		    								.addValue(PARAM_ITEM_INCIDENCIAS, item.getIncidencias())
		    								.addValue(PARAM_ITEM_ESTADO, item.getEstado());
		    
		    // Establecer parametros y ejecutar SP
		    Map<String,Object> data = llamarSP.execute(parametros);
		    
		    // Obteniendo el total de filas afectadas al ejecutar SP
		    totalRegistrosAfectado += (Integer) data.get(TOTAL_FILAS_AFECTADAS);
		    
		    // Obteniendo codigo de item
		    int codigoItem = (Integer)data.get(PARAM_ITEM_CODITEM_SALIDA);

		    // Estableciendo codigo de bulto
		    item.setCodItem(codigoItem);
		    
		    // ==== Registro de ItemsComponentes ====
		    totalRegistrosAfectado += registrarItemComponente(item);
		    
		    // ==== Registro de Bulto-Componente ====
		    totalRegistrosAfectado += registrarBultoDetalle(bulto, item);
	    }
	    
		return totalRegistrosAfectado;
	}

	private int registrarBultoDetalle(Bulto bulto, Item item) {
		logger.info("registrarBultoDetalle");

		int totalRegistrosAfectado = 0;
		// Obteniendo lista de lineas de la guia a agregar
		ListaItemComponente listaItemComponente = item.getListaItemComponente();

		// Si existen lineas entonces registrarlos
		if (listaItemComponente != null && listaItemComponente.getLista() != null) {
			// Instanciando variable para llamado de SP
			SimpleJdbcCall llamarSP = new SimpleJdbcCall(jdbcTemplate)
					.withProcedureName(SP_REGISTRAR_DET_BULTO);

			for (ItemComponente itemComponente : listaItemComponente.getLista()) {

				// Estableciendo parametros de entrada al SP
				SqlParameterSource parametros = new MapSqlParameterSource()
						.addValue(PARAM_ITEM_CODITEM, item.getCodItem())
						.addValue(PARAM_BULTO_CODBULTO, bulto.getCodBulto())
						.addValue(PARAM_ITEM_CODCOMPONENTE,	itemComponente.getCodComponente());

				// Establecer parametros y ejecutar SP
				Map<String, Object> data = llamarSP.execute(parametros);

				// Obteniendo el total de filas afectadas al ejecutar SP
				totalRegistrosAfectado = (Integer) data.get(TOTAL_FILAS_AFECTADAS);
			}
		} 
		else {
			// Instanciando variable para llamado de SP
			SimpleJdbcCall llamarSP = new SimpleJdbcCall(jdbcTemplate)
					.withProcedureName(SP_REGISTRAR_DET_BULTO);

			// Estableciendo parametros de entrada al SP
			SqlParameterSource parametros = new MapSqlParameterSource()
					.addValue(PARAM_ITEM_CODITEM, item.getCodItem())
					.addValue(PARAM_BULTO_CODBULTO, bulto.getCodBulto())
					.addValue(PARAM_ITEM_CODCOMPONENTE, 0);

			// Establecer parametros y ejecutar SP
			Map<String, Object> data = llamarSP.execute(parametros);

			// Obteniendo el total de filas afectadas al ejecutar SP
			totalRegistrosAfectado = (Integer) data.get(TOTAL_FILAS_AFECTADAS);
		}
		
		return totalRegistrosAfectado;
	}
	
	private int registrarItemComponente(Item item){
		logger.info("registrarItemComponente");
		
		int totalRegistrosAfectado = 0;
		
		// Obteniendo lista de lineas de la guia a agregar
	    ListaItemComponente listaItemComponente = item.getListaItemComponente();
	    
	    // Si existen lineas entonces registrarlos
	    if(listaItemComponente != null && listaItemComponente.getLista() != null){
		    // Instanciando variable para llamado de SP
		    SimpleJdbcCall llamarSP = new SimpleJdbcCall(jdbcTemplate).withProcedureName(SP_REGISTRAR_ITEM_COMPONENTE);
	
		    for (ItemComponente itemComponente : listaItemComponente.getLista()){
		    	// Estableciendo codigo de item
		    	itemComponente.setCodItem(item.getCodItem());
		    	
			    // Estableciendo parametros de entrada al SP
			    SqlParameterSource parametrosDetalle = new MapSqlParameterSource()
						    								.addValue(PARAM_ITEM_CODITEM, itemComponente.getCodItem())
						    								.addValue(PARAM_ITEM_CODCOMPONENTE , itemComponente.getCodComponente())
						    								.addValue(PARAM_ITEM_CODIFICACION, itemComponente.getCodificacion())
						    								.addValue(PARAM_ITEM_CODITEMUNION, itemComponente.getItem()==null?null:itemComponente.getItem().getCodItem())
						    								.addValue(PARAM_ITEM_UNIONITEM, itemComponente.getUnionItem());
			    
			    // Establecer parametros y ejecutar SP
			    Map<String,Object> dataDetalle = llamarSP.execute(parametrosDetalle);
			    
			    // Obteniendo el total de filas afectadas al ejecutar SP
			    totalRegistrosAfectado += (Integer) dataDetalle.get(TOTAL_FILAS_AFECTADAS);
		    }
	    }
	    
	    return totalRegistrosAfectado;
	}
	
	private int actualizarEstadoItem(Item item){
		logger.info("actualizarEstadoItem");
		
		// Instanciando variable para llamado de SP
	    SimpleJdbcCall llamarSP = new SimpleJdbcCall(jdbcTemplate).withProcedureName(SP_ACTUALIZAR_ESTADO_ITEM);

	    // Estableciendo parametros de entrada al SP
	    SqlParameterSource parametros = new MapSqlParameterSource()
	    								.addValue(PARAM_ITEM_CODITEM, item.getCodItem())
	    								.addValue(PARAM_ITEM_ESTADO, item.getEstado());
	    
	    // Establecer parametros y ejecutar SP
	    Map<String,Object> data = llamarSP.execute(parametros);
	    
	    // Obteniendo el total de filas afectadas al ejecutar SP
	    int totalRegistrosAfectado = (Integer) data.get(TOTAL_FILAS_AFECTADAS);
	        
	    return totalRegistrosAfectado;
	}

	@Override
	public Guia obtenerGuia(Guia guia) {
		logger.info("obtenerGuia");

		// Instanciando variable para llamado de SP
	    SimpleJdbcCall llamarSP = new SimpleJdbcCall(jdbcTemplate).withProcedureName(SP_OBTENER_GUIA).
	    						  returningResultSet(LISTADO, new RowMapper<Guia>(){
									@Override
									public Guia mapRow(final ResultSet rs, final int numRow) throws SQLException
								    {
								        final Guia guia = new Guia();
								        guia.setCodGuia(rs.getInt(CODGUIA));
								        guia.setSerie(rs.getString(SERIE));
								        guia.setNumero(rs.getString(NUMERO));
								        
								        Mantenimiento mantenimiento =  new Mantenimiento();
								        mantenimiento.setCodMantenimiento(rs.getInt(CODMANTENIMIENTO));
								        guia.setMantenimiento(mantenimiento);
								        
								        Prestamo prestamo = new Prestamo();
								        prestamo.setCodPrestamo(rs.getInt(CODPRESTAMO));
								        guia.setPrestamo(prestamo);
								        
								        Solicitud solicitud = new Solicitud();
								        solicitud.setCodSolicitud(rs.getInt(CODSOLICITUD));
								        guia.setSolicitud(solicitud);
								        
								        Transporte transporte = new Transporte();
								        transporte.setCodTransporte(rs.getInt(CODTRANSPORTE));
								        guia.setTransporte(transporte);
								        
								        Venta venta = new Venta();
								        venta.setCodVenta(rs.getInt(CODVENTA));
								        guia.setVenta(venta);
								        
								        TipoGuia tipoGuia =  new TipoGuia();
								        tipoGuia.setCodigo(rs.getInt(CODTIPOGUIA));
								        tipoGuia.setDescripcion(rs.getString(TIPOGUIA));
								        guia.setTipoGuia(tipoGuia);
								        
								        guia.setEstado(rs.getString(ESTADO));
								        guia.setFechaRegistro(rs.getDate(FECHAREGISTRO)==null?null:rs.getDate(FECHAREGISTRO).toString());
								        guia.setFechaEmision(rs.getDate(FECHAEMISION)==null?null:rs.getDate(FECHAEMISION).toString());
								        guia.setFechaRecepcion(rs.getDate(FECHARECEPCION)==null?null:rs.getDate(FECHARECEPCION).toString());
								        
								        Tienda tiendaDestino= new Tienda();
								        tiendaDestino.setCodigo(rs.getInt(CODTIENDADESTINO));
								        tiendaDestino.setNombre(rs.getString(NOMBRETIENDADESTINO));
								        tiendaDestino.setDireccion(rs.getString(DIRECCIONTIENDADESTINO));
								        tiendaDestino.setDistrito(rs.getString(DISTRITOTIENDADESTINO));
								        guia.setTiendaDestino(tiendaDestino);
								       
								        Tienda tiendaOrigen= new Tienda();
								        tiendaOrigen.setCodigo(rs.getInt(CODTIENDAORIGEN));
								        tiendaOrigen.setNombre(rs.getString(NOMBRETIENDAORIGEN));
								        tiendaOrigen.setDireccion(rs.getString(DIRECCIONTIENDAORIGEN));
								        tiendaOrigen.setDistrito(rs.getString(DISTRITOTIENDAORIGEN));
								        guia.setTiendaOrigen(tiendaOrigen);
								        
								        return guia;
								    }
	    						  }
								)
								.returningResultSet(LISTADO_LINEAS, new RowMapper<LineaGuia>(){
									@Override
									public LineaGuia mapRow(final ResultSet rs, final int numRow) throws SQLException
								    {
								        final LineaGuia lineaGuia = new LineaGuia();
								        lineaGuia.setNumeroLinea(rs.getInt(DET_NROLINEA));
								        lineaGuia.setCodGuia(rs.getInt(CODGUIA));
								        
								        Producto producto = new Producto();
								        producto.setCodigo(rs.getInt(DET_CODPRODUCTO));
								        producto.setDescripcion(rs.getString(DET_NOMPRODUCTO));
								        producto.setCodProductoProveedor(rs.getString(DET_CODPRODUCTOPROVEEDOR));
								        producto.setUnidadMedida(rs.getString(DET_UNIDADMEDIDA));
								        
								        NivelProducto nivelProducto = new NivelProducto();
								        nivelProducto.setCodigo(rs.getInt(DET_CODNIVELPROD));
								        nivelProducto.setDescripcion(rs.getString(DET_NIVELPRODUCTODESCRIPCION));
								        producto.setNivelProducto(nivelProducto);
								        
								        NivelColor nivelColor = new NivelColor();
								        nivelColor.setCodigo(rs.getInt(DET_CODNIVELCOLOR));
								        nivelColor.setCodNivelProducto(rs.getInt(DET_CODNIVELPROD));
								        nivelColor.setDescripcion(rs.getString(DET_COLORDESCRIPCION));
								        producto.setNivelColor(nivelColor);
								        
								        NivelTipo nivelTipo = new NivelTipo();
								        nivelTipo.setCodigo(rs.getInt(DET_CODNIVELTIPO));
								        nivelTipo.setCodNivelProducto(rs.getInt(DET_CODNIVELPROD));
								        nivelTipo.setDescripcion(rs.getString(DET_TIPODESCRIPCION));
								        producto.setNivelTipo(nivelTipo);
								        
								        NivelMaterial nivelMaterial = new NivelMaterial();
								        nivelMaterial.setCodigo(rs.getInt(DET_CODNIVELMATERIAL));
								        nivelMaterial.setCodNivelProducto(rs.getInt(DET_CODNIVELPROD));
								        nivelMaterial.setDescripcion(rs.getString(DET_MATERIALDESCRIPCION));
								        producto.setNivelMaterial(nivelMaterial);
								        
								        lineaGuia.setProducto(producto);
								        
								        lineaGuia.setCantidad(rs.getInt(DET_CANTIDAD));
								        
								        return lineaGuia;
								    }
	    						  })
	    						  .returningResultSet(LISTADO_LINEAS_ITEM, new RowMapper<LineaGuiaItem>(){
										@Override
										public LineaGuiaItem mapRow(final ResultSet rs, final int numRow) throws SQLException
									    {
									        final LineaGuiaItem lineaGuiaItem = new LineaGuiaItem();
									        lineaGuiaItem.setNroLinea(rs.getInt(DET_NROLINEA));
									        lineaGuiaItem.setCodGuia(rs.getInt(CODGUIA));
									        
									        Item item = new Item();
									        item.setCodItem(rs.getInt(ITEM_CODITEM));
									        item.setCodificacion(rs.getString(ITEM_CODIFICACION));
									        item.setPrecioCompra(rs.getDouble(ITEM_PRECIOCOMPRA));
									        item.setEstado(rs.getString(ESTADO));
									        
									        Tienda tienda = new Tienda();
									        tienda.setCodigo(rs.getInt(ITEM_CODTIENDA));
									        item.setTienda(tienda);
									        
									        Moneda moneda = new Moneda();
									        moneda.setCodigo(rs.getInt(ITEM_CODMONEDA));
									        item.setMoneda(moneda);
									        
									        Producto producto = new Producto();
									        producto.setCodigo(rs.getInt(DET_CODPRODUCTO));
									        producto.setCodProductoProveedor(rs.getString(DET_CODPRODUCTOPROVEEDOR));
									        producto.setDescripcion(rs.getString(DET_NOMPRODUCTO));
									        producto.setComponentes(rs.getString(DET_COMPPRODUCTO));
									        item.setProducto(producto);
									        
									        lineaGuiaItem.setItem(item); 								        
	
									        return lineaGuiaItem;
									    }
		    						  });

	    // Estableciendo parametros de entrada al SP
	    SqlParameterSource parametros = new MapSqlParameterSource()
	    								.addValue(PARAM_NUMERO, guia.getNumero())
	    								.addValue(PARAM_SERIE, guia.getSerie()); 

	    // Establecer parametros y ejecutar SP
        Map<String,Object> data = llamarSP.execute(parametros);

        // Obteniendo lista generada de ejecutar SP
		@SuppressWarnings("unchecked")
		List<Guia> listaGuia = (List<Guia>)data.get(LISTADO);
        
		// Declarando objeto Guia Obtenido
 		Guia GuiaObtenido = null;
 		
 		if (logger.isDebugEnabled() && listaGuia != null)
        {
            logger.debug("size=" + listaGuia.size());
        }
		
 		if (listaGuia != null && listaGuia.size()>0){
 			// Obteniendo el primer elemento de la lista de Guia
 			GuiaObtenido = listaGuia.get(0);
 		
	        // Obteniendo lista de lineas generada de ejecutar SP
			@SuppressWarnings("unchecked")
			List<LineaGuia> listaLineaGuia = (List<LineaGuia>)data.get(LISTADO_LINEAS);
	        
			// Instanciando objeto ListaLineaGuia
			ListaLineaGuia listaLineaGuiaResultado = new ListaLineaGuia();
	        // Estableciendo resultado al objeto listaLineaGuiaResultado
			listaLineaGuiaResultado.setLista(listaLineaGuia);
	        
			// --------------------------------------------------------------------------------------------
			// Obteniendo lista de lineas-item generada de ejecutar SP
			@SuppressWarnings("unchecked")
			List<LineaGuiaItem> listaLineaGuiaItem = (List<LineaGuiaItem>)data.get(LISTADO_LINEAS_ITEM);
			
			for (LineaGuia lineaGuia : listaLineaGuiaResultado.getLista()){
				
				// Instanciando objeto ListaLineaGuiaItem
				ListaLineaGuiaItem listaLineaGuiaItemResultado =  new ListaLineaGuiaItem();
				
				for(LineaGuiaItem lineaGuiaItem : listaLineaGuiaItem){
					if( lineaGuiaItem.getNroLinea() == lineaGuia.getNumeroLinea()){
						listaLineaGuiaItemResultado.add(lineaGuiaItem);
					}
				}
			
				if(listaLineaGuiaItemResultado.size()>0){
					lineaGuia.setListaLineaGuiaItem(listaLineaGuiaItemResultado);
				}
			}
			// --------------------------------------------------------------------------------------------
			
			// Asignando lista de lineas al objeto Guia creado
			GuiaObtenido.setListaLineaGuia(listaLineaGuiaResultado);
			
	        if (logger.isDebugEnabled() && listaLineaGuiaResultado != null)
	        {
	            logger.debug("sizeLineas=" + listaLineaGuiaResultado.size());
	        }
 		}

		return GuiaObtenido;
	}
	
	@Override
	public Guia obtenerGuiaCodGuia(Guia guia) {
		logger.info("obtenerGuiaCodGuia");

		// Instanciando variable para llamado de SP
	    SimpleJdbcCall llamarSP = new SimpleJdbcCall(jdbcTemplate).withProcedureName(SP_OBTENER_GUIA_CODGUIA).
	    						  returningResultSet(LISTADO, new RowMapper<Guia>(){
									@Override
									public Guia mapRow(final ResultSet rs, final int numRow) throws SQLException
								    {
								        final Guia guia = new Guia();
								        guia.setCodGuia(rs.getInt(CODGUIA));
								        guia.setSerie(rs.getString(SERIE));
								        guia.setNumero(rs.getString(NUMERO));
								        
								        Mantenimiento mantenimiento =  new Mantenimiento();
								        mantenimiento.setCodMantenimiento(rs.getInt(CODMANTENIMIENTO));
								        guia.setMantenimiento(mantenimiento);
								        
								        Prestamo prestamo = new Prestamo();
								        prestamo.setCodPrestamo(rs.getInt(CODPRESTAMO));
								        guia.setPrestamo(prestamo);
								        
								        Solicitud solicitud = new Solicitud();
								        solicitud.setCodSolicitud(rs.getInt(CODSOLICITUD));
								        guia.setSolicitud(solicitud);
								        
								        Transporte transporte = new Transporte();
								        transporte.setCodTransporte(rs.getInt(CODTRANSPORTE));
								        guia.setTransporte(transporte);
								        
								        Venta venta = new Venta();
								        venta.setCodVenta(rs.getInt(CODVENTA));
								        guia.setVenta(venta);
								        
								        TipoGuia tipoGuia =  new TipoGuia();
								        tipoGuia.setCodigo(rs.getInt(CODTIPOGUIA));
								        tipoGuia.setDescripcion(rs.getString(TIPOGUIA));
								        guia.setTipoGuia(tipoGuia);
								        
								        guia.setEstado(rs.getString(ESTADO));
								        guia.setFechaRegistro(rs.getDate(FECHAREGISTRO).toString());
								        guia.setFechaEmision(rs.getDate(FECHAEMISION).toString());
								        guia.setFechaRecepcion(rs.getDate(FECHARECEPCION)==null?null:rs.getDate(FECHARECEPCION).toString());
								        
								        Tienda tiendaDestino= new Tienda();
								        tiendaDestino.setCodigo(rs.getInt(CODTIENDADESTINO));
								        tiendaDestino.setNombre(rs.getString(NOMBRETIENDADESTINO));
								        tiendaDestino.setDireccion(rs.getString(DIRECCIONTIENDADESTINO));
								        tiendaDestino.setDistrito(rs.getString(DISTRITOTIENDADESTINO));
								        guia.setTiendaDestino(tiendaDestino);
								       
								        Tienda tiendaOrigen= new Tienda();
								        tiendaOrigen.setCodigo(rs.getInt(CODTIENDAORIGEN));
								        tiendaOrigen.setNombre(rs.getString(NOMBRETIENDAORIGEN));
								        tiendaOrigen.setDireccion(rs.getString(DIRECCIONTIENDAORIGEN));
								        tiendaOrigen.setDistrito(rs.getString(DISTRITOTIENDAORIGEN));
								        guia.setTiendaOrigen(tiendaOrigen);
								        
								        return guia;
								    }
	    						  }
								)
								.returningResultSet(LISTADO_LINEAS, new RowMapper<LineaGuia>(){
									@Override
									public LineaGuia mapRow(final ResultSet rs, final int numRow) throws SQLException
								    {
								        final LineaGuia lineaGuia = new LineaGuia();
								        lineaGuia.setNumeroLinea(rs.getInt(DET_NROLINEA));
								        lineaGuia.setCodGuia(rs.getInt(CODGUIA));
								        
								        Producto producto = new Producto();
								        producto.setCodigo(rs.getInt(DET_CODPRODUCTO));
								        producto.setDescripcion(rs.getString(DET_NOMPRODUCTO));
								        producto.setCodProductoProveedor(rs.getString(DET_CODPRODUCTOPROVEEDOR));
								        producto.setUnidadMedida(rs.getString(DET_UNIDADMEDIDA));
								        
								        NivelProducto nivelProducto = new NivelProducto();
								        nivelProducto.setCodigo(rs.getInt(DET_CODNIVELPROD));
								        nivelProducto.setDescripcion(rs.getString(DET_NIVELPRODUCTODESCRIPCION));
								        producto.setNivelProducto(nivelProducto);
								        
								        NivelColor nivelColor = new NivelColor();
								        nivelColor.setCodigo(rs.getInt(DET_CODNIVELCOLOR));
								        nivelColor.setCodNivelProducto(rs.getInt(DET_CODNIVELPROD));
								        nivelColor.setDescripcion(rs.getString(DET_COLORDESCRIPCION));
								        producto.setNivelColor(nivelColor);
								        
								        NivelTipo nivelTipo = new NivelTipo();
								        nivelTipo.setCodigo(rs.getInt(DET_CODNIVELTIPO));
								        nivelTipo.setCodNivelProducto(rs.getInt(DET_CODNIVELPROD));
								        nivelTipo.setDescripcion(rs.getString(DET_TIPODESCRIPCION));
								        producto.setNivelTipo(nivelTipo);
								        
								        NivelMaterial nivelMaterial = new NivelMaterial();
								        nivelMaterial.setCodigo(rs.getInt(DET_CODNIVELMATERIAL));
								        nivelMaterial.setCodNivelProducto(rs.getInt(DET_CODNIVELPROD));
								        nivelMaterial.setDescripcion(rs.getString(DET_MATERIALDESCRIPCION));
								        producto.setNivelMaterial(nivelMaterial);
								        
								        lineaGuia.setProducto(producto);
								        
								        lineaGuia.setCantidad(rs.getInt(DET_CANTIDAD));
								        
								        return lineaGuia;
								    }
	    						  })
	    						  .returningResultSet(LISTADO_LINEAS_ITEM, new RowMapper<LineaGuiaItem>(){
										@Override
										public LineaGuiaItem mapRow(final ResultSet rs, final int numRow) throws SQLException
									    {
									        final LineaGuiaItem lineaGuiaItem = new LineaGuiaItem();
									        lineaGuiaItem.setNroLinea(rs.getInt(DET_NROLINEA));
									        lineaGuiaItem.setCodGuia(rs.getInt(CODGUIA));
									        
									        Item item = new Item();
									        item.setCodItem(rs.getInt(ITEM_CODITEM));
									        item.setCodificacion(rs.getString(ITEM_CODIFICACION));
									        item.setPrecioCompra(rs.getDouble(ITEM_PRECIOCOMPRA));
									        item.setEstado(rs.getString(ESTADO));
									        
									        Tienda tienda = new Tienda();
									        tienda.setCodigo(rs.getInt(ITEM_CODTIENDA));
									        item.setTienda(tienda);
									        
									        Moneda moneda = new Moneda();
									        moneda.setCodigo(rs.getInt(ITEM_CODMONEDA));
									        item.setMoneda(moneda);
									        
									        Producto producto = new Producto();
									        producto.setCodigo(rs.getInt(DET_CODPRODUCTO));
									        producto.setCodProductoProveedor(rs.getString(DET_CODPRODUCTOPROVEEDOR));
									        producto.setDescripcion(rs.getString(DET_NOMPRODUCTO));
									        item.setProducto(producto);
									        
									        lineaGuiaItem.setItem(item); 								        
	
									        return lineaGuiaItem;
									    }
		    						  });

	    // Estableciendo parametros de entrada al SP
	    SqlParameterSource parametros = new MapSqlParameterSource()
	    								.addValue(PARAM_CODGUIA, guia.getCodGuia()); 

	    // Establecer parametros y ejecutar SP
        Map<String,Object> data = llamarSP.execute(parametros);

        // Obteniendo lista generada de ejecutar SP
		@SuppressWarnings("unchecked")
		List<Guia> listaGuia = (List<Guia>)data.get(LISTADO);
        
		// Declarando objeto Guia Obtenido
 		Guia GuiaObtenido = null;
 		
 		if (logger.isDebugEnabled() && listaGuia != null)
        {
            logger.debug("size=" + listaGuia.size());
        }
		
 		if (listaGuia != null && listaGuia.size()>0){
 			// Obteniendo el primer elemento de la lista de Guia
 			GuiaObtenido = listaGuia.get(0);
 		
	        // Obteniendo lista de lineas generada de ejecutar SP
			@SuppressWarnings("unchecked")
			List<LineaGuia> listaLineaGuia = (List<LineaGuia>)data.get(LISTADO_LINEAS);
	        
			// Instanciando objeto ListaLineaGuia
			ListaLineaGuia listaLineaGuiaResultado = new ListaLineaGuia();
	        // Estableciendo resultado al objeto listaLineaGuiaResultado
			listaLineaGuiaResultado.setLista(listaLineaGuia);
	        
			// --------------------------------------------------------------------------------------------
			// Obteniendo lista de lineas-item generada de ejecutar SP
			@SuppressWarnings("unchecked")
			List<LineaGuiaItem> listaLineaGuiaItem = (List<LineaGuiaItem>)data.get(LISTADO_LINEAS_ITEM);
			
			for (LineaGuia lineaGuia : listaLineaGuiaResultado.getLista()){
				
				// Instanciando objeto ListaLineaGuiaItem
				ListaLineaGuiaItem listaLineaGuiaItemResultado =  new ListaLineaGuiaItem();
				
				for(LineaGuiaItem lineaGuiaItem : listaLineaGuiaItem){
					if( lineaGuiaItem.getNroLinea() == lineaGuia.getNumeroLinea()){
						listaLineaGuiaItemResultado.add(lineaGuiaItem);
					}
				}
			
				if(listaLineaGuiaItemResultado.size()>0){
					lineaGuia.setListaLineaGuiaItem(listaLineaGuiaItemResultado);
				}
			}
			// --------------------------------------------------------------------------------------------
			
			// Asignando lista de lineas al objeto Guia creado
			GuiaObtenido.setListaLineaGuia(listaLineaGuiaResultado);
			
	        if (logger.isDebugEnabled() && listaLineaGuiaResultado != null)
	        {
	            logger.debug("sizeLineas=" + listaLineaGuiaResultado.size());
	        }
 		}

		return GuiaObtenido;
	}
	
	public int modificarGuia(Guia guia){
		logger.info("modificarGuia");
		
		// Instanciando variable para llamado de SP
	    SimpleJdbcCall llamarSP = new SimpleJdbcCall(jdbcTemplate).withProcedureName(SP_MODIFICAR_GUIA);

	    // Estableciendo parametros de entrada al SP
	    SqlParameterSource parametros = new MapSqlParameterSource()
	    								.addValue(PARAM_CODGUIA, guia.getCodGuia())
	    								.addValue(PARAM_ESTADO, guia.getEstado())
	    								.addValue(PARAM_FECHARECEPCION, guia.getFechaRecepcion());
	    
	    // Establecer parametros y ejecutar SP
	    Map<String,Object> data = llamarSP.execute(parametros);
	    
	    // Obteniendo el total de filas afectadas al ejecutar SP
	    int totalRegistrosAfectado = (Integer) data.get(TOTAL_FILAS_AFECTADAS);
	        
	    return totalRegistrosAfectado;
	}
	
	@Override
	public Guia obtenerGuiaOrdenCompra(Guia guia) {
		logger.info("obtenerGuiaOrdenCompra");

		// Instanciando variable para llamado de SP
		SimpleJdbcCall llamarSP = new SimpleJdbcCall(jdbcTemplate)
				.withProcedureName(SP_OBTENER_GUIA_ORDENCOMPRA)
				.returningResultSet(LISTADO, new RowMapper<Guia>() {
					@Override
					public Guia mapRow(final ResultSet rs, final int numRow)
							throws SQLException {
						final Guia guia = new Guia();
						guia.setCodGuia(rs.getInt(CODGUIA));
						guia.setSerie(rs.getString(SERIE));
						guia.setNumero(rs.getString(NUMERO));

						Transporte transporte = new Transporte();
						transporte.setCodTransporte(rs.getInt(CODTRANSPORTE));
						guia.setTransporte(transporte);

						TipoGuia tipoGuia = new TipoGuia();
						tipoGuia.setCodigo(rs.getInt(CODTIPOGUIA));
						tipoGuia.setDescripcion(rs.getString(TIPOGUIA));
						guia.setTipoGuia(tipoGuia);

						guia.setEstado(rs.getString(ESTADO));
						guia.setFechaRegistro(rs.getDate(FECHAREGISTRO)==null?null:rs.getDate(FECHAREGISTRO).toString());
						guia.setFechaEmision(rs.getDate(FECHAEMISION)==null?null:rs.getDate(FECHAEMISION).toString());
						guia.setFechaRecepcion(rs.getDate(FECHARECEPCION)==null?null:rs.getDate(FECHARECEPCION).toString());

						Tienda tiendaDestino = new Tienda();
						tiendaDestino.setCodigo(rs.getInt(CODTIENDADESTINO));
						tiendaDestino.setNombre(rs.getString(NOMBRETIENDADESTINO));
						guia.setTiendaDestino(tiendaDestino);

						Tienda tiendaOrigen = new Tienda();
						tiendaOrigen.setCodigo(rs.getInt(CODTIENDAORIGEN));
						tiendaOrigen.setNombre(rs.getString(NOMBRETIENDAORIGEN));
						guia.setTiendaOrigen(tiendaOrigen);

						return guia;
					}
				})
				.returningResultSet(LISTADO_LINEAS,
						new RowMapper<OrdenCompra>() {
							@Override
							public OrdenCompra mapRow(final ResultSet rs,
									final int numRow) throws SQLException {
								final OrdenCompra ordenCompra = new OrdenCompra();
								ordenCompra.setCodOC(rs.getInt(ORDENCOMPRA));

								return ordenCompra;
							}
						});
		// Estableciendo parametros de entrada al SP
		SqlParameterSource parametros = new MapSqlParameterSource()
		        .addValue(PARAM_NUMERO, guia.getNumero())
				.addValue(PARAM_SERIE,	guia.getSerie());
		// Establecer parametros y ejecutar SP
		Map<String, Object> data = llamarSP.execute(parametros);

		// Obteniendo lista generada de ejecutar SP
		@SuppressWarnings("unchecked")
		List<Guia> listaGuia = (List<Guia>) data.get(LISTADO);

		// Declarando objeto Guia Obtenido
		Guia GuiaObtenido = null;

		if (logger.isDebugEnabled() && listaGuia != null) {
			logger.debug("size=" + listaGuia.size());
		}

		if (listaGuia != null && listaGuia.size() > 0) {
			// Obteniendo el primer elemento de la lista de Guia
			GuiaObtenido = listaGuia.get(0);

			// Obteniendo lista de lineas generada de ejecutar SP
			@SuppressWarnings("unchecked")
			List<OrdenCompra> listaOrdenCompra = (List<OrdenCompra>) data.get(LISTADO_LINEAS);

			// Instanciando objeto ListaOrdenCompra
			ListaOrdenCompra listaOrdenCompraResultado = new ListaOrdenCompra();
			// Estableciendo resultado al objeto listaLineaGuiaResultado
			listaOrdenCompraResultado.setLista(listaOrdenCompra);
			// Asignando lista de lineas al objeto Guia creado
			GuiaObtenido.setListaOrdenCompra(listaOrdenCompraResultado);

			if (logger.isDebugEnabled() && listaOrdenCompraResultado != null) {
				logger.debug("sizeLineas=" + listaOrdenCompraResultado.size());
			}
		}

		return GuiaObtenido;
	}
	
	@Override
	public int validarGuia(Guia guia){
		logger.info("validarGuia");
		
		// Instanciando variable para llamado de SP
	    SimpleJdbcCall llamarSP = new SimpleJdbcCall(jdbcTemplate).withProcedureName(SP_VALIDAR_GUIA)
	 				             .returningResultSet(LISTADO, new RowMapper<Guia>() {
	 	          @Override
	 	          public Guia mapRow(final ResultSet rs, final int numRow) throws SQLException {
	 						final Guia guia = new Guia();
	 						guia.setCodGuia(rs.getInt(CONTAR));
	 						
	 						return guia;
	 	          }
	 				     });

	    // Estableciendo parametros de entrada al SP
	    SqlParameterSource parametros = new MapSqlParameterSource()
	    								.addValue(PARAM_NUMERO, guia.getNumero())
	    								.addValue(PARAM_SERIE, guia.getSerie());
	    
	 // Establecer parametros y ejecutar SP
	 		Map<String, Object> data = llamarSP.execute(parametros);

	 		// Obteniendo lista generada de ejecutar SP
	 		@SuppressWarnings("unchecked")
	 		List<Guia> listaGuia = (List<Guia>) data.get(LISTADO);

	 		// Declarando objeto Guia Obtenido
	 		Guia GuiaObtenido = null;

	 		if (logger.isDebugEnabled() && listaGuia != null) {
	 			logger.debug("size=" + listaGuia.size());
	 		}

	 		if (listaGuia != null && listaGuia.size() > 0) {
	 			// Obteniendo el primer elemento de la lista de Guia
	 			GuiaObtenido = listaGuia.get(0);
	 		}
	 		
	    // Obteniendo el total de filas afectadas al ejecutar SP
	    int totalRegistrosAfectado = GuiaObtenido.getCodGuia();
	        
	    return totalRegistrosAfectado;
	}
	
	public int limpiarGuiaDetalle(Guia guia){
		logger.info("limpiarGuiaDetalle");
        
		int resultado = 0;
		
		// Instanciando variable para llamado de SP Eliminar items registrados en transferencia pasadas
	    SimpleJdbcCall llamarSPLimpiarGuiaDetalle = new SimpleJdbcCall(jdbcTemplate).withProcedureName(SP_LIMPIAR_GUIA_DETALLE);
	    // Agregar parametro codigo de cliente
	    llamarSPLimpiarGuiaDetalle.execute(new MapSqlParameterSource()
										     .addValue(PARAM_CODGUIA, guia.getCodGuia()));
    		    
	    return resultado;
	}
	
	@Override
	public ListaGuia listarPrestamoGuia(Guia guia) {
		logger.info("listarPrestamoGuia");

		// Instanciando variable para llamado de SP
		SimpleJdbcCall llamarSP = new SimpleJdbcCall(jdbcTemplate).withProcedureName(SP_LISTAR_PRESTAMO_GUIA).returningResultSet(
						LISTADO, new RowMapper<Guia>() {
							@Override
							public Guia mapRow(final ResultSet rs, final int numRow) throws SQLException {
								final Guia guia = new Guia();
								guia.setCodGuia(rs.getInt(CODGUIA));
							    guia.setSerie(rs.getString(SERIE)==null?null:rs.getString(SERIE));
							    guia.setNumero(rs.getString(NUMERO)==null?null:rs.getString(NUMERO));
								
								Prestamo prestamo = new Prestamo();
								prestamo.setCodPrestamo(rs.getInt(CODPRESTAMO));

								Cliente cliente = new Cliente();
								cliente.setCodCliente(rs.getInt(PRESTAMO_CODCLIENTE));
								cliente.setTipoDocumento(rs.getString(PRESTAMO_TIPODOCUMENTO));
								cliente.setNroDocumento(rs.getString(CLIENTE_NRODOCUMENTO));
								cliente.setRazonSocial(rs.getString(CLIENTE_RAZONSOCIAL));
								cliente.setDireccion(rs.getString(CLIENTE_DIRECCION));
								prestamo.setCliente(cliente);
								
								Tienda tienda = new Tienda();
								tienda.setCodigo(rs.getInt(PRESTAMO_CODTIENDA));
								tienda.setDescripcion(rs.getString(PRESTAMO_NOMBRETIENDA));
								prestamo.setTienda(tienda);

								Usuario usuario = new Usuario();
								usuario.setCodUsuario(rs.getInt(PRESTAMO_CODUSUARIO));
								usuario.setNombresyApellidos(rs.getString(USUARIO_NOMBRESYAPELLIDOS));
								prestamo.setUsuario(usuario);
								
								Diseniador diseniador = new Diseniador();
								diseniador.setCodDiseniador(rs.getInt(PRESTAMO_CODDISENIADOR));
								diseniador.setNombresyApellidos(rs.getString(PRESTAMO_DISENIADORNOMBRESYAPELLIDOS));
								prestamo.setDiseniador(diseniador);

								prestamo.setPeriodoxDias(rs.getInt(PRESTAMO_PERIODOXDIAS));
								prestamo.setFechaInicio(rs.getDate(PRESTAMO_FECHAINICIO).toString());
								prestamo.setFechaFin(rs.getDate(PRESTAMO_FECHAFIN).toString());
								prestamo.setEstado(rs.getString(PRESTAMO_ESTADO));
								prestamo.setFechaRegistro(rs.getDate(PRESTAMO_FECHAREGISTRO).toString());
								
								guia.setPrestamo(prestamo);
								
								return guia;
								
							}
						});

		// Estableciendo parametros de entrada al SP
		SqlParameterSource parametros = new MapSqlParameterSource()
		                   .addValue(PARAM_CODPRESTAMO, guia.getPrestamo().getCodPrestamo())
		                   .addValue(PARAM_CODCLIENTE, guia.getPrestamo().getCliente().getCodCliente())
		                   .addValue(PARAM_ESTADO, guia.getPrestamo().getEstado());

		// Establecer parametros y ejecutar SP
		Map<String, Object> data = llamarSP.execute(parametros);

		// Obteniendo lista generada de ejecutar SP
		@SuppressWarnings("unchecked")
		List<Guia> listaGuia = (List<Guia>) data.get(LISTADO);

		// Instanciando objeto ListaPrestamo
		ListaGuia listaGuiaResultado = new ListaGuia();
		// Estableciendo resultado al objeto listaPrestamoResultado
		listaGuiaResultado.setLista(listaGuia);

		if (logger.isDebugEnabled() && listaGuiaResultado != null) {
			logger.debug("size=" + listaGuiaResultado.size());
		}

		return listaGuiaResultado;
	}
	
	public int actualizarEstadoGuia(Guia guia){
		logger.info("actualizarEstadoGuia");
		
		// Instanciando variable para llamado de SP
	    SimpleJdbcCall llamarSP = new SimpleJdbcCall(jdbcTemplate).withProcedureName(SP_ACTUALIZAR_ESTADO_GUIA);

	    // Estableciendo parametros de entrada al SP
	    SqlParameterSource parametros = new MapSqlParameterSource()
	    								.addValue(PARAM_CODGUIA, guia.getCodGuia())
	    								.addValue(PARAM_ESTADO, guia.getEstado());
	    
	    // Establecer parametros y ejecutar SP
	    Map<String,Object> data = llamarSP.execute(parametros);
	    
	    // Obteniendo el total de filas afectadas al ejecutar SP
	    int totalRegistrosAfectado = (Integer) data.get(TOTAL_FILAS_AFECTADAS);
	        
	    return totalRegistrosAfectado;
	}
	
}
